package br.affCorp.controller.rdf.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import br.affCorp.controller.rdf.GenericRDF;
import br.affCorp.model.ObjetoDeAprendizagemDTO;
import br.affCorp.util.vocabulary.rdf.LOM;
import br.affCorp.util.vocabulary.rdf.SIOC;
import br.util.AFFCorpWebUtil;
import br.util.AppJsfUtil;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.sparql.core.ResultBinding;

public class ObjetoDeAprendizagemRDF extends GenericRDF {

	private UsuarioRDF usuarioRDF;

	public Collection<ObjetoDeAprendizagemDTO> obterPorFiltro(
			ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO) {
		return null;
	}

	public void inserir(ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO) {

		Model modelNovo = ModelFactory.createDefaultModel();
		Model modelAntigo = ModelFactory.createDefaultModel();

		preencherResource(objetoDeAprendizagemDTO, modelNovo);

		modelAntigo.read(this.obterArquivoRDF(objetoDeAprendizagemDTO
				.getDominio(), objetoDeAprendizagemDTO.getCodigo()), "");

		setModel(modelNovo);

		preencherResource(objetoDeAprendizagemDTO, getModel());

		Map<String, String> map = new HashMap<String, String>();

		map.put("lom", LOM.getURI());
		getModel().setNsPrefixes(map);

		super.salvarArquivoRDF(getModel(),
				objetoDeAprendizagemDTO.getDominio(), objetoDeAprendizagemDTO
						.getCodigo());

	}

	protected void preencherResource(
			ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO, Model model) {
		String resourceId = super.obterResourceID(objetoDeAprendizagemDTO,
				objetoDeAprendizagemDTO.getCodigo());

		Resource lomGeneral = model.createResource(resourceId, LOM.General);

		if (!AppJsfUtil.isNullOrEmpty(objetoDeAprendizagemDTO.getEntrada())) {
			lomGeneral.addProperty(LOM.entry, objetoDeAprendizagemDTO
					.getEntrada());
		}

		if (!AppJsfUtil.isNullOrEmpty(objetoDeAprendizagemDTO.getTitulo())) {
			lomGeneral.addProperty(LOM.title, objetoDeAprendizagemDTO
					.getTitulo());
		}
		if (!AppJsfUtil.isNullOrEmpty(objetoDeAprendizagemDTO.getDescricao())) {
			lomGeneral.addProperty(LOM.description, objetoDeAprendizagemDTO
					.getDescricao());
		}
		usuarioRDF = new UsuarioRDF();
		Resource siocUser = usuarioRDF
				.associarUsuarioObjetoDeAprendizagem(objetoDeAprendizagemDTO);

		model.add(siocUser.getModel());
		lomGeneral.addProperty(SIOC.has_owner, siocUser);

		Map<String, String> map = new HashMap<String, String>();

		map.put("sioc", SIOC.getURI());
		map.put("lom", LOM.getURI());
		model.setNsPrefixes(map);
	}

	public Resource associarObjetoDeAprendizagemUsuario(
			ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO, Model model) {

		String resourceId = super.obterResourceID(objetoDeAprendizagemDTO,
				objetoDeAprendizagemDTO.getCodigo());

		Resource resource = model.createResource(resourceId, LOM.General);

		if (!AppJsfUtil.isNullOrEmpty(objetoDeAprendizagemDTO.getEntrada())) {
			resource.addProperty(LOM.entry, objetoDeAprendizagemDTO
					.getEntrada());
		}

		if (!AppJsfUtil.isNullOrEmpty(objetoDeAprendizagemDTO.getTitulo())) {
			resource
					.addProperty(LOM.title, objetoDeAprendizagemDTO.getTitulo());
		}
		if (!AppJsfUtil.isNullOrEmpty(objetoDeAprendizagemDTO.getDescricao())) {
			resource.addProperty(LOM.description, objetoDeAprendizagemDTO
					.getDescricao());
		}

		return resource;
	}

	public ObjetoDeAprendizagemDTO obterObjetoDeAprendizagem(Resource resource) {

		ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO = new ObjetoDeAprendizagemDTO();

		String titulo = obterValorDaPropriedade(resource, LOM.title);
		String descricao = obterValorDaPropriedade(resource, LOM.description);

		if (!AFFCorpWebUtil.isNullOrEmpty(titulo)) {
			if (AFFCorpWebUtil.isNullOrEmpty(objetoDeAprendizagemDTO
					.getTitulo())) {
				objetoDeAprendizagemDTO.setTitulo(titulo);
			}
		}
		if (!AFFCorpWebUtil.isNullOrEmpty(descricao)) {
			if (AFFCorpWebUtil.isNullOrEmpty(objetoDeAprendizagemDTO
					.getDescricao())) {
				objetoDeAprendizagemDTO.setDescricao(descricao);
			}
		}

		return objetoDeAprendizagemDTO;
	}

	public ObjetoDeAprendizagemDTO obterObjetoDeAprendizagem(Resource resource,
			ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO) {

		String titulo = obterValorDaPropriedade(resource, LOM.title);
		String descricao = obterValorDaPropriedade(resource, LOM.description);

		if (!AFFCorpWebUtil.isNullOrEmpty(titulo)) {
			if (AFFCorpWebUtil.isNullOrEmpty(objetoDeAprendizagemDTO
					.getTitulo())) {
				objetoDeAprendizagemDTO.setTitulo(titulo);
			}
		}
		if (!AFFCorpWebUtil.isNullOrEmpty(descricao)) {
			if (AFFCorpWebUtil.isNullOrEmpty(objetoDeAprendizagemDTO
					.getDescricao())) {
				objetoDeAprendizagemDTO.setDescricao(descricao);
			}
		}

		return objetoDeAprendizagemDTO;
	}

	public ObjetoDeAprendizagemDTO obterPorID(
			ObjetoDeAprendizagemDTO objetoDeAprendizagemDTO) {
		getModel().read(
				this.obterArquivoRDF(objetoDeAprendizagemDTO.getDominio(),
						objetoDeAprendizagemDTO.getCodigo()), "");

		StringBuffer querySB = new StringBuffer();

		String id = "<" + objetoDeAprendizagemDTO.getLocalizacao() + ">";

		querySB.append(" PREFIX sioc: <" + SIOC.getURI() + "> 		");
		querySB.append(" PREFIX lom: <" + LOM.getURI() + "> 		");
		querySB.append(" SELECT 									");
		querySB.append(" 	?titulo	 								");
		querySB.append(" 	?descricao	 								");
		querySB.append(" 	?oa	 								");
		querySB.append(" WHERE	 									");
		querySB.append(" 	{	 									");
		querySB.append("  		?oa lom:description ?descricao		.	  		");
		querySB.append("  		?oa lom:title ?titulo		.	  		");
		querySB.append("  		FILTER (?oa = " + id + ")								");
		querySB.append(" 	}										");

		Query query = QueryFactory.create(querySB.toString());

		QueryExecution qe = QueryExecutionFactory.create(query, getModel());
		try {
			ResultSet results = qe.execSelect();
			if (results.hasNext()) {
				ResultBinding res = (ResultBinding) results.next();
				RDFNode rdfNode = res.get("oa");

				Resource resource = getModel().getResource(rdfNode.toString());

				return this.obterObjetoDeAprendizagem(resource,
						objetoDeAprendizagemDTO);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			qe.close();
		}

		return null;
	}
}
